package com.apobates.jforum2.troll.forum.biz;

import com.apobates.jforum2.troll.forum.entity.Board;
import com.apobates.jforum2.troll.forum.entity.BoardConfig;
import com.apobates.jforum2.troll.regular.ForumEntityStatusEnum;
import com.apobates.jforum2.troll.utils.core.api.ActionEventCulpritor;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

/**
 * 版块的业务接口
 * @author xiaofanku
 * @since 20200510
 */
public interface BoardService {
    /**
     * 锁定指定的版块
     *
     * @param id 版块ID
     * @param boardGroupId 版块组/卷ID
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> lock(long id, int boardGroupId, ActionEventCulpritor culpritor);
    
    /**
     * 解锁指定的版块
     *
     * @param id 版块ID
     * @param boardGroupId 版块组/卷ID
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> releaseLock(long id, int boardGroupId, ActionEventCulpritor culpritor);
    
    /**
     * 将版块标记为删除
     *
     * @param id 版块ID
     * @param boardGroupId 版块组/卷ID
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> remove(long id, int boardGroupId, ActionEventCulpritor culpritor);
    
    /**
     * 编辑指定的版块
     *
     * @param id 版块ID
     * @param boardGroupId 版块组/卷ID
     * @param description 版块的描述
     * @param status 版块的状态
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> edit(long id, int boardGroupId, String description, ForumEntityStatusEnum status, ActionEventCulpritor culpritor)throws IllegalArgumentException;
    
    /**
     * 创建新的版块
     *
     * @param boardGroupId 版块组( 卷)ID
     * @param title 版块的名称
     * @param description 版块的描述
     * @param encodeImageAddr 图标地址(编码后的格式)
     * @param status 版块的状态
     * @param ranking 排序
     * @return
     */
    Optional<Board> create(int boardGroupId, String title, String description, String encodeImageAddr, ForumEntityStatusEnum status, int ranking);
    
    /**
     * 更新指定的版块
     *
     * @param id 版块ID
     * @param updateBoard 更新的版块属性实例<br/>
     * 若许更新版块的图标需要对其进行编码<br/>
     * 不更新图标需要将其设置为null<br/>
     * @return
     */
    Optional<Boolean> edit(long id, Board updateBoard)throws IllegalArgumentException;
    
    /**
     * 会员收藏版块
     *
     * @param id 版块ID
     * @param culpritor 操作的肇事信息
     * @return 若已经存在收藏记录抛出异常
     */
    Optional<Boolean> favorite(long id, ActionEventCulpritor culpritor)throws IllegalStateException;
    
    /**
     * 取消会员的收藏
     *
     * @param id 版块ID
     * @param culpritor 操作的肇事信息
     * @return 若收藏记录不存在抛出异常
     */
    Optional<Boolean> removeFavorite(long id, ActionEventCulpritor culpritor)throws IllegalStateException;
    
    /**
     * 批量取消会员的收藏
     *
     * @param idSet 版块ID集合
     * @param culpritor 操作的肇事信息
     * @return 返回的结果中表示取消成功的版块ID
     */
    List<Long> removeFavorites(Set<Long> idSet, ActionEventCulpritor culpritor)throws IllegalStateException;
    
    /**
     * 是否可以收藏, 可以返回true
     *
     * @param id 版块ID
     * @param memberId 会员ID
     * @return
     */
    boolean isFavorited(long id, long memberId);
    
    /**
     * 更新配置的配置文件,只允许版主执行
     *
     * @param id 版块ID
     * @param boardGroupId 版块组/卷ID
     * @param configId 版块配置文件ID
     * @param updateConfig 版块配置的属性实例
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> editBoardConfig(long id, int boardGroupId, long configId, BoardConfig updateConfig, ActionEventCulpritor culpritor)throws IllegalArgumentException;
    
    /**
     * 编辑子栏目
     *
     * @since 20200427
     * @param id 子栏目ID
     * @param title 子栏目的名称
     * @param description 子栏目的描述
     * @param directoryNames 目录名称,需要唯一
     * @param status 子栏目的状态
     * @return
     */
    Optional<Boolean> editTerm(long id, String title, String description, String directoryNames, ForumEntityStatusEnum status)throws IllegalArgumentException;
    
    /**
     * 创建新的子栏目(原生版块)
     *
     * @since 20200427
     * @param sectionId 栏目ID
     * @param title 子栏目的名称
     * @param description 子栏目的描述
     * @param directoryNames 目录名称,需要唯一
     * @param status 子栏目的状态
     * @return
     */
    long buildOrigin(int sectionId, String title, String description, String directoryNames, ForumEntityStatusEnum status)throws IllegalArgumentException,IllegalStateException;
    
    /**
     * 检查子栏目的目录名称唯一性.
     *
     * @since 20200427
     * @param directoryNames 子栏目的目录名称
     * @return 可以使用返回true,若想知道失败的原因可以捕获异常
     */
    Optional<Boolean> checkTermDirectNameUnique(String directoryNames)throws IllegalArgumentException,IllegalStateException;
    
    /**
     * 编辑子栏目时检查目录是否被使用.
     *
     * @since 20200427
     * @param directoryNames 子栏目的目录名称
     * @param termId 编辑的子栏目ID
     * @return 可以使用返回true,若想知道失败的原因可以捕获异常
     */
    Optional<Boolean> checkTermDirectNameUnique(String directoryNames, long termId)throws IllegalArgumentException,IllegalStateException;
    
    
    /**
     * 查看所有版块.包括所有状态的,前端不要使用
     *
     * @return
     */
    Stream<Board> getAll();
    
    /**
     * 所有可用的版块
     *
     * @return
     */
    Stream<Board> getAllUsed();
    
    /**
     * 查看指定版块组( 卷)中的所有版块
     *
     * @param boardGroupId 版块组( 卷)ID
     * @return
     */
    Stream<Board> getAllByVolumesId(int boardGroupId);
    
    /**
     * 查看指定的子栏目
     *
     * @since 20200427
     * @param idList 栏目ID列表
     * @return
     */
    Stream<Board> getAllTermById(Collection<Long> idList);
    /**
     * 查看版块.不包括删除的
     * @param idList 版块ID列表
     * @return 
     */
    Stream<Board> getAllUsed(Collection<Long> idList);
    /**
     * 查看指定栏目下的子栏目(原生版块)
     *
     * @since 20200427
     * @param sectionId 栏目ID.
     * @return
     */
    List<Board> getAllTermByOriginId(int sectionId);
    
    /**
     * 查看所有子栏目(原生版块)
     *
     * @since 20200427
     * @return
     */
    List<Board> getAllTerm();
    
    /**
     * 查看指定的子栏目
     *
     * @since 20200427
     * @param directoryNames 子栏目的目录名称
     * @return
     */
    Optional<Board> getTermByDirectoryNames(String directoryNames);
    
    /**
     * 查看指定的子栏目
     *
     * @since 20200427
     * @param termId 子栏目ID
     * @return
     */
    Optional<Board> getTermById(long termId);
    
    /**
     * [Cacheable]查看指定的版块
     *
     * @param id 版块ID
     * @return
     */
    Optional<Board> get(long id);
    
    /**
     * 查看指定版块的名称
     *
     * @param idList 版块ID
     * @return
     */
    Map<Long, String> getAllById(Collection<Long> idList);
    
    /**
     * 查看指定版块组( 卷)中的可显示版块,不包括删除的
     *
     * @param boardGroupId 版块组(卷)ID
     * @return
     */
    List<Board> getAllUsedByVolumesId(int boardGroupId);
    //List<BoardReplica> getAllUsedByVolumesId(int boardGroupId);
    /**
     * 统计指定会员收藏/星标的版块数量
     * 
     * @param memberId 会员ID
     * @return 
     */
    //long countFavoritesForMember(long memberId);

    /**
     * 查看会员收藏/星标的版块
     * @param memberId 会员ID
     * @param size 显示的数量
     * @return
     */
    //Stream<Board> getMemberFavoritesNoStats(long memberId, int size);
    /**
     * 查看会员收藏/星标的版块,加载版块统计
     *
     * @param memberId 会员ID
     * @param size 显示的数量
     * @return
     */
    //Stream<BoardReplica> getMemberFavorites(long memberId, int size);
    
    /**
     * 查看指定会员收藏/星标的版块,加载版块
     * 
     * @param memberId 会员ID
     * @param pageable 分页请求参数
     * @return 
     */
    //Page<BoardActionCollectionReplica> getFavoritesForMember(long memberId, Pageable pageable);
    
    // 版块合并
    // ETC
    
    /**
     * 查看指定的版块, 级联加载版块组(卷)
     *
     * @param id 版块ID
     * @param boardGroupId 版块组(卷)ID
     * @return
     */
    //Optional<BoardReplica> get(long id, int boardGroupId);
    
    /**
     * 查看指定的子栏目(原生版块),同时加载所属的栏目(原生版块组)
     * 
     * @since 20200427
     * @param directoryNames 子栏目的目录名称
     * @return
     */
    //Optional<BoardReplica> getTermRelateSection(String directoryNames);
    
    /**
     * 查看指定的版块. 级联加载版块配置
     *
     * @param id 版块ID
     * @return
     */
    //Optional<BoardReplica> getBoardConfig(long id);
    
    /**
     * 查看指定的版块. 级联关联版块的统计信息
     *
     * @param id 版块ID
     * @return
     */
    //Optional<BoardReplica> getBoardStats(long id);
}